/**
 * Copyright © 2012, Grid Protection Alliance.  All Rights Reserved.
 *
 * Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
 * the NOTICE file distributed with this work for additional information regarding copyright ownership.
 * The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may
 * not use this file except in compliance with the License. You may obtain a copy of the License at:
 *
 * http://www.opensource.org/licenses/eclipse-1.0.php
 *
 * Unless agreed to in writing, the subject software distributed under the License is distributed on an
 * "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
 * License for the specific language governing permissions and limitations.
 */
package org.gridprotectionalliance.oam.proxy.impl

import slick.session.{ Session, Database }

class H2ConfigStore(db: Database) extends ConfigStore {

  db.withSession { implicit s: Session =>
    if (!DAO.makeTableMap.contains(DAO.Historians.tableName)) (DAO.Historians.ddl).create
  }
  def getConfigForType(typ: String): List[HistorianConfig] = db.withSession { implicit s: Session =>
    DAO.getConfigForType(typ)
  }

  def list(): List[HistorianConfig] = db.withSession { implicit s: Session =>
    DAO.getAllConfig
  }

  def removeByName(name: String): Unit = db.withSession { implicit s: Session =>
    DAO.removeByName(name)
  }

  def insert(cfg: HistorianConfig): Unit = db.withSession { implicit s: Session =>
    DAO.insert(cfg)
  }

}

import slick.driver.H2Driver.simple._
import slick.jdbc.meta.MTable

object DAO {

  def makeTableMap(implicit sess: Session): Map[String, MTable] =
    MTable.getTables.list()(sess).map(t => (t.name.name, t)).toMap

  object Historians extends Table[(String, String, String)]("HISTORIAN_CONFIG") {
    def name = column[String]("name", O.PrimaryKey)
    def typ = column[String]("type")
    def connString = column[String]("connString")
    def * = name ~ typ ~ connString
  }

  def getAllConfig(implicit s: Session): List[HistorianConfig] = {
    val query = for { h <- Historians } yield h.name ~ h.typ ~ h.connString
    query.list.map(x => HistorianConfig(x._1, x._2, x._3))
  }

  def getConfigForType(typ: String)(implicit s: Session): List[HistorianConfig] = {
    val query = for { h <- Historians if (h.typ === typ) } yield h.name ~ h.typ ~ h.connString
    query.list.map(x => HistorianConfig(x._1, x._2, x._3))
  }

  def removeByName(name: String)(implicit s: Session): Unit = {
    val query = for {
      h <- Historians if h.name === name
    } yield h.name
    query.mutate(rec => rec.delete())
  }

  def insert(cfg: HistorianConfig)(implicit s: Session): Unit = {
    Historians.insert(cfg.name, cfg.typ, cfg.connString)
  }

}